package com.tbit.uqbike.task;

import com.tbit.uqbike.TerGatewayMain;
import com.tbit.uqbike.service.db.DbService;
import com.tbit.uqbike.service.redis.RedisService;
import com.tbit.uqbike.tergateway.config.TerGatewayConfig;
import com.tbit.uqbike.tergateway.data.TerGatewayData;
import com.tbit.uqbike.tergateway.entity.CacheData;
import com.tbit.uqbike.tergateway.entity.TerTempData;
import com.tbit.uqbike.tergateway.pojo.TerBattery;
import com.tbit.uqbike.tergateway.pojo.TerInfo;
import com.tbit.uqbike.tergateway.pojo.TerOnline;
import com.tbit.uqbike.tergateway.pojo.TerPos;
import com.tbit.uqbike.util.BatUpdateResult;
import com.tbit.uqbike.util.CollExUtils;
import com.tbit.uqbike.util.Pair;
import com.tbit.uqbike.util.TurnCacheDataToHashSet;

import java.util.Date;
import java.util.LinkedList;
import java.util.List;

/**
 * Created by MyWin on 2018/1/25 0025.
 */
public class RedisBatWriter implements Runnable {
    private static org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(RedisBatWriter.class);

    private TurnCacheDataToHashSet redisTurn = new TurnCacheDataToHashSet();

    @Override
    public void run() {
        writeAllCacheData();
    }

    private void writeAllCacheData() {
        try {
            List<TerTempData> mnos = TerGatewayData.getAllTerTempData();
            List<CacheData> updateCacheList = new LinkedList<>();
            List<CacheData> updateDbCacheList = new LinkedList<>();
            for (TerTempData data : mnos) {
                CacheData cd = data.getDelayUpdateCacheData();
                if (cd.haveRedisCacheData()) {
                    updateCacheList.add(cd);
                }
                if (cd.haveDbCacheData()) {
                    updateDbCacheList.add(cd);
                }
            }
            writeAllCacheDataToRedis(updateCacheList);
            writeAllCacheDataToDb(updateDbCacheList);
        } catch (Exception e) {
            logger.error("writeAllCacheData", e);
        }
    }

    private void writeAllCacheDataToRedis(List<CacheData> updateCacheList) {
        try {
            if (updateCacheList.isEmpty()) {
                return;
            }
            redisTurn.resetCnt();
            List<List<Pair<String, List<Pair<String, String>>>>> redisPkgData = CollExUtils.spiltList(updateCacheList, TerGatewayConfig.iRedisBatSize, redisTurn);
            Date start = new Date();
            RedisService redis = TerGatewayMain.getRedis();
            if (!redisPkgData.isEmpty()) {
                for (List<Pair<String, List<Pair<String, String>>>> item : redisPkgData) {
                    redis.Hash_BatSetValue(item);
                }
            }
            Date end = new Date();
            long lMs = end.getTime() - start.getTime();
            logger.info(String.format("Bat Write [%d] Ter Cache Data,Pos:%d,Battery:%d,Status:%d,PkgDt:%d,Use:%d",
                    redisTurn.getTotalCnt(), redisTurn.getPosCnt(), redisTurn.getBatCnt(), redisTurn.getStatusCnt(), redisTurn.getActiveCnt(), lMs));
        } catch (Exception e) {
            logger.error("writeAllCacheDataToRedis", e);
        }
    }

    private void writeAllCacheDataToDb(List<CacheData> updateCacheList) {
        try {
            if (updateCacheList.isEmpty()) {
                return;
            }
            BatUpdateResult batUpdate = new BatUpdateResult(TerGatewayConfig.iDbBatSize);
            batUpdate.resetCnt();
            for (CacheData item : updateCacheList) {
                batUpdate.readCacheData(item);
            }
            DbService dbService = TerGatewayMain.getDbService();
            Date start = new Date();
            if (!batUpdate.batLists.isEmpty()) {
                for (List<TerBattery> list : batUpdate.batLists) {
                    dbService.batUpdateTerBatter(list);
                }
            }
            if (!batUpdate.posLists.isEmpty()) {
                for (List<TerPos> list : batUpdate.posLists) {
                    dbService.batUpdateTerLastPos(list);
                }
            }
            if (!batUpdate.infoLists.isEmpty()) {
                for (List<TerInfo> list : batUpdate.infoLists) {
                    dbService.batUpdateTerInfos(list);
                }
            }
            if (!batUpdate.batOnlines.isEmpty()) {
                for (List<TerOnline> list : batUpdate.batOnlines) {
                    dbService.batUpdateTerOnlines_Dt(list);
                }
            }
            Date end = new Date();
            long lMs = end.getTime() - start.getTime();
            logger.info(String.format("Bat Write Db[%d],Pos:%d,Battery:%d,TerInfo:%d,Use:%d",
                    batUpdate.getTotalCnt(), batUpdate.getPosCnt(), batUpdate.getBatCnt(), batUpdate.getInfoCnt(), lMs));
        } catch (Exception e) {
            logger.error("writeAllCacheDataToDb", e);
        }
    }
}
